package flc.ast.activity;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;

import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.PathUtils;
import com.blankj.utilcode.util.ToastUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.OptionalDouble;

import flc.ast.BaseAc;
import flc.ast.R;
import flc.ast.databinding.ActivityNoiseBinding;
import flc.ast.utils.Content;
import flc.ast.utils.MyMediaRecorder;
import stark.common.basic.utils.FileUtil;
import stark.common.basic.utils.StkPermissionHelper;

public class NoiseActivity extends BaseAc<ActivityNoiseBinding> {

    private MyMediaRecorder mRecorder;
    private boolean hasRecord = false;
    private ArrayList<Integer> arrayList = new ArrayList<>();
    private Handler mHandler;
    float volume = 10000;

    private final Runnable mTaskUpdateTime = new Runnable() {
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        public void run() {
            if (!hasRecord) return;
            volume = mRecorder.getMaxAmplitude();  //获取声压值
            if (volume > 0 && volume < 1000000) {
                float value = 20 * (float) (Math.log10(volume));
                int val = (int) value;
                mDataBinding.tvCurrent.setText(val + "");
                arrayList.add(new Integer(val));
                setView();
                updatePointer(val);
            }
            mHandler.postDelayed(this, 1000);
        }
    };

    @Override
    protected int onCreate() {
        return R.layout.activity_noise;
    }

    @Override
    protected void initView() {
        mDataBinding.ivNoiseBack.setOnClickListener(v -> onBackPressed());

        mDataBinding.tvStartMeasure.setOnClickListener(this);

        mRecorder = new MyMediaRecorder();
        mHandler = new Handler();
    }

    @Override
    protected void onClickCallback(View v) {
        switch (v.getId()) {
            case R.id.tvStartMeasure://开始/停止测量
                if (hasRecord) {
                    hasRecord = false;
                    stopTime();
                    mDataBinding.tvStartMeasure.setText(R.string.start_measure);
                } else {
                    getPermission();
                }
                break;
        }
    }

    @Override
    protected void initData() {

    }

    //获取权限
    private void getPermission() {
        StkPermissionHelper.permission(Manifest.permission.RECORD_AUDIO)
                .reqPermissionDesc(getString(R.string.get_audio_permission))
                .callback(new StkPermissionHelper.ACallback() {
                    @Override
                    public void onGranted() {
                        startTest();
                    }
                }).request();
    }

    //开始检测
    private void startTest() {
        String musicPath = FileUtil.generateFilePath(Content.myTemp, ".mp3");
        try {
            mRecorder.setMyRecAudioFile(FileUtils.getFileByPath(musicPath));
            if (mRecorder.startRecorder()) {
                arrayList.clear();
                hasRecord = true;
                startTime();
                mDataBinding.tvStartMeasure.setText(getString(R.string.stop_measure));
            } else {
                ToastUtils.showShort(R.string.audio_fail_tips);
            }
        } catch (Exception e) {
            ToastUtils.showShort(R.string.audio_fail_tips2);
            e.printStackTrace();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    private void setView() {
        int max = Collections.max(arrayList);
        int min = Collections.min(arrayList);
        OptionalDouble avgAge = arrayList.stream().mapToInt(Integer::intValue).average();
        int avg = (int) avgAge.getAsDouble();
        mDataBinding.tvMax.setText(max + "");
        mDataBinding.tvAverage.setText(avg + "");
    }

    private void updatePointer(float db) {
        runOnUiThread(() -> {
            float targetAngle = (db / 120) * 180 - 90;
            mDataBinding.ivPointer.animate()
                    .rotation(targetAngle)
                    .setDuration(150)
                    .setInterpolator(new AccelerateDecelerateInterpolator())
                    .start();
        });
    }

    private void startTime() {
        mHandler.post(mTaskUpdateTime);
    }

    private void stopTime() {
        mHandler.removeCallbacks(mTaskUpdateTime);
    }

    @Override
    protected void onStop() {
        super.onStop();
        stopTime();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        FileUtils.delete(PathUtils.getFilesPathExternalFirst() + Content.myTemp);
        stopTime();
    }
}